/**
**************************************************************************************
*Founder Effect                                                                      *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"
#include "LUA_Player.h"
#include "../game/EntityManager.h"
#include "../Kernel.h"

extern Kernel* g_kernel;

LUA_Player::LUA_Player(void)
{
}

LUA_Player::~LUA_Player(void)
{
}

Player* LUA_Player::m_player = NULL;


/** Inialize the player */
int LUA_Player::Init( lua_State *L )
{
    m_player = EntityManager::GetInstance()->GetPlayer();
    return 0;
}


/** Set the face of the entity */
int LUA_Player::SetFace( lua_State *L )
{ 
    int face = (int)luaL_checknumber( L, 1 );
    if ( m_player )
        m_player->SetFace( face );
    return 0;
}
/** Set the name of the entity */
int LUA_Player::SetName( lua_State *L )
{
    // retrieve the name from lua
    std::string name = luaL_checkstring( L, 1 );
    if ( m_player )
        m_player->SetName( name );
    return 0;
}
/** Set the state of the entity */
int LUA_Player::SetState( lua_State *L )
{
    std::string state = luaL_checkstring( L, 1 );
    if ( m_player )
        m_player->SetState( state );
    return 0;
}
/** Set the position of the entity */
int LUA_Player::SetPosition( lua_State *L )
{
    float x = (float)luaL_checknumber( L, 1 );
    float y = (float)luaL_checknumber( L, 2 );
    if ( m_player )
        m_player->m_physObject.SetPosition( Vector2f(x, y) );
    return 0;
}
/** Set the speed */
int LUA_Player::SetVelocity( lua_State *L )
{
    float speed = (float)luaL_checknumber( L, 1 );

    if ( m_player )
        m_player->m_fSpeed = speed;
    return 0;
}
/** Add a state */
int LUA_Player::AddState( lua_State *L )
{

    return 0;
}

/** Get the face of the entity */
int LUA_Player::GetFace( lua_State *L )
{   
    if ( m_player ) {
        lua_pushnumber( L, m_player->GetFace() ); 
        return 1;
    } 
    return 0;
}
/** Get the name of the entity */
int LUA_Player::GetName( lua_State *L )
{
    if ( m_player ) {
        lua_pushstring( L, m_player->GetName().c_str() ); 
        return 1;
    } 
    return 0;
}

/** Get the position of the entity */
int LUA_Player::GetPosX( lua_State *L )
{
    if ( m_player ) {
        lua_pushnumber( L, m_player->m_physObject.GetPosition().x  ); 
        return 1;
    } 
    return 0;
}
/** Get the position of the entity */
int LUA_Player::GetPosY( lua_State *L )
{
    if ( m_player ) {
        lua_pushnumber( L, m_player->m_physObject.GetPosition().y ); 
        return 1;
    } 
    return 0;
}

/** Get the speed */
int LUA_Player::GetSpeed( lua_State *L )
{
    if ( m_player ) {
        lua_pushnumber( L, m_player->m_fSpeed ); 
        return 1;
    } 
    return 0;
}

/** Add a state */
int LUA_Player::GetCurrentState( lua_State *L )
{
    if ( m_player ) {
        lua_pushstring( L, m_player->GetState().c_str() ); 
        return 1;
    } 
    return 0;
}

/** Give the Player an item */
int LUA_Player::GiveItem( lua_State *L )
{
    if ( m_player ) {
        std::string entName = luaL_checkstring( L, 1 );
        IEntity* ent = EntityManager::GetInstance()->Find( entName );
        if ( ent )
        {
            // give the player the entity
            m_player->PickUpItem( ent );
        }
    } 
    return 0;
}

/** Disable the player from moving from input */
int LUA_Player::EnableInput( lua_State *L )
{
    if ( m_player )
    {
        int enable = int(luaL_checknumber( L, 1 ));
        g_kernel->GetCvars()->SetCvarValue( "i_registerInput", enable );
    }
    return 0;
}

/*------------------------------------------------
    Mission Handling 
------------------------------------------------*/

/** Check the status of a mission */
int LUA_Player::CheckMissionStatus( lua_State *L )
{
    if( m_player )
    {
        std::string mission = luaL_checkstring( L, 1 );
        lua_pushnumber( L, m_player->m_missions.GetMissionStatus( mission ) );
        return 1;
    }
    return 0;
}
/** Check to see if this mission exists */
int LUA_Player::HasMission( lua_State *L )
{
    if( m_player )
    {
        std::string mission = luaL_checkstring( L, 1 );
        lua_pushboolean( L, (int)m_player->m_missions.HasMission( mission ) );
        return 1;
    }
    return 0;
}
/** Set the status of a mission */
int LUA_Player::SetMissionStatus( lua_State *L )
{
    if( m_player )
    {
        std::string mission = luaL_checkstring( L, 1 );
        int         status  = (int)luaL_checknumber( L, 2 );
        switch ( status )
        {
        case M_COMPLETE:
            m_player->m_missions.CompleteMission( mission );
        break;
        case M_FAILED:
            m_player->m_missions.FailedMission( mission );
        break;
        default:
            m_player->m_missions.GetMission( mission )->SetStatus( status );
            break;
        
        }
    }
    return 0;
}


// -- Bind to LUA
#define method(name) {#name, LUA_Player::name}

const luaL_reg LUA_Player::methods[] = {
        method(Init),
        method(SetFace),
        method(SetName),
        method(SetState),
        method(SetPosition),
        method(SetVelocity),
        method(AddState),
        method(GetFace),
        method(GetName),
        method(GetPosX),
        method(GetPosY),
        method(GetSpeed),
        method(GetCurrentState),
        method(GiveItem),
        method(EnableInput),
        /*---------------------------
            Missions
        ----------------------------*/
        method(CheckMissionStatus),
        method(HasMission),
        method(SetMissionStatus),
        {NULL, NULL}
};

// - Bind to lua
int luaopen_LUA_Player(lua_State *L) {
    luaL_openlib(L, "player", LUA_Player::methods, 0);
 	return 0;
}